using Infrastructure.Attribute;
using Infrastructure.Extensions;
using JTZY.Model.Order.Dto;
using JTZY.Model.Order;
using JTZY.Repository;
using JTZY.Service.Order.IOrderService;
using Infrastructure;
using Infrastructure.Enums;
using static JTZY.Common.GlobalEnumVars;
using JTZY.Common;
using Essensoft.Paylink.WeChatPay.V3.Domain;
using JTZY.Model.Product;
using Mapster;

namespace JTZY.Service.Order
{
    /// <summary>
    /// 退货单表Service业务层处理
    /// </summary>
    [AppService(ServiceType = typeof(ICorecmsbillreshipService), ServiceLifetime = LifeTime.Transient)]
    public class CorecmsbillreshipService : BaseService<Corecmsbillreship>, ICorecmsbillreshipService
    {
        private readonly ICorecmsbillreshipitemService _corecmsbillreshipitemService;
        private readonly IRefshipdetailService _refshipdetailService;

        public CorecmsbillreshipService(ICorecmsbillreshipitemService corecmsbillreshipitemService, IRefshipdetailService refshipdetailService) 
        {
            _corecmsbillreshipitemService= corecmsbillreshipitemService;
            _refshipdetailService= refshipdetailService;
        }
        /// <summary>
        /// 查询退货单表列表
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        /// <summary>
        /// 查询退货单表列表
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        public PagedInfo<CorecmsbillreshipDto> GetList(CorecmsbillreshipQueryDto parm)
        {
            var predicate = QueryExp(parm);

            var response = Queryable()
                .Where(predicate.ToExpression())
                .ToPage<Corecmsbillreship, CorecmsbillreshipDto>(parm);

            return response;
        }


        public PagedInfo<billreshipitemDto> GetStatistics(CorecmsbillreshipQueryDto parm)
        {
            var predicate = QueryExp(parm);

            var response = Queryable()
                .LeftJoin<Corecmsbillreshipitem>((it, item) => it.ReshipId == item.ReshipId)
                .LeftJoin<Corecmsorderitem>((it, item,orderitem) => item.OrderItemsId == orderitem.Id)
                .LeftJoin<Refshipdetail>((it, item, orderitem, detail) => item.ReshipId == detail.ReshipId && item.ProductId==detail.ProductId)
                .LeftJoin<Prodinfo>((it, item, orderitem, detail, prod) => detail.SnCode == prod.SnCode)
                .Where(predicate.ToExpression())
                .GroupBy((it, item, orderitem, detail, prod) => new { it.ReshipId, item.ProductId, item.Addon, item.ImageUrl })
                .Select((it, item, orderitem, detail, prod) => new billreshipitemDto
                {
                    Addon= item.Addon,
                    ImageUrl= item.ImageUrl,
                    OrderNums= SqlFunc.AggregateCount(it.ReshipId),
                    Nums= SqlFunc.AggregateSum(item.Nums),
                    WaitNums= SqlFunc.AggregateSum(prod.Status==1 ? 1 : 0),
                    ShipNums= SqlFunc.AggregateSum(prod.Status == 2 ? 1 : 0),
                    ReceiveNums= SqlFunc.AggregateSum(prod.Status == 3 ? 1 : 0),
                    Amount= SqlFunc.AggregateSum(item.Nums* orderitem.Price)
                })

                .ToPage<billreshipitemDto>(parm);

            var ext=Queryable()
                .LeftJoin<Corecmsbillreshipitem>((it, item) => it.ReshipId == item.ReshipId)
                .LeftJoin<Corecmsorderitem>((it, item, orderitem) => item.OrderItemsId == orderitem.Id)
                .LeftJoin<Refshipdetail>((it, item, orderitem, detail) => item.ReshipId == detail.ReshipId && item.ProductId == detail.ProductId)
                .LeftJoin<Prodinfo>((it, item, orderitem, detail, prod) => detail.SnCode == prod.SnCode)
                .Where(predicate.ToExpression())
                .Select((it, item, orderitem, detail, prod) => new 
                {
                    OrderNums = SqlFunc.AggregateCount(it.ReshipId),
                    Nums = SqlFunc.AggregateSum(item.Nums),
                    WaitNums = SqlFunc.AggregateSum(prod.Status == 1?1:0),
                    ShipNums = SqlFunc.AggregateSum(prod.Status == 2 ? 1 : 0),
                    ReceiveNums = SqlFunc.AggregateSum(prod.Status == 3 ? 1 : 0),
                    Amount = SqlFunc.AggregateSum(item.Nums * orderitem.Price)
                }).First();
            response.Extra = new Dictionary<string, object>()
            {
                { "OrderNums",ext.OrderNums },
                { "Nums",ext.Nums },
                { "WaitNums",ext.WaitNums },
                { "ShipNums",ext.ShipNums },
                { "ReceiveNums",ext.ReceiveNums },
                { "Amount",ext.Amount }
            };
            return response;
        }

        /// <summary>
        /// 获取详情
        /// </summary>
        /// <param name="ReshipId"></param>
        /// <returns></returns>
        public Corecmsbillreship GetInfo(string ReshipId)
        {
            var response = Queryable()
                .Where(x => x.ReshipId == ReshipId)
                .First();

            return response;
        }

        /// <summary>
        /// 添加退货单表
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public Corecmsbillreship AddCorecmsbillreship(Corecmsbillreship model)
        {
            return Insertable(model).ExecuteReturnEntity();
        }

        /// <summary>
        /// 修改退货单表
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public int UpdateCorecmsbillreship(Corecmsbillreship model)
        {
            return Update(model, true);
        }

        /// <summary>
        /// 创建退货单
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="orderId"></param>
        /// <param name="aftersalesId"></param>
        /// <param name="aftersalesItems"></param>
        /// <returns></returns>
        public WebApiCallBack ToAdd(long userId, string orderId, Corecmsbillaftersales aftersales, List<Corecmsbillaftersalesitem> aftersalesItems, List<Billaftersaledetail> billAftersalesDetails, string sourceType = "0")
        {
            var jm = new WebApiCallBack();

            if (aftersalesItems == null || aftersalesItems.Count <= 0)
            {
                jm.msg = "退货数量为空，不需要生成退货单";
                jm.data = jm.code = 13209;
                return jm;
            }

            var model = new Corecmsbillreship();
            model.ReshipId = CommonHelper.GetSerialNumberType((int)SerialNumberType.退货单编号);
            model.OrderId = orderId;
            model.AftersalesId = aftersales.AftersalesId;
            model.UserId = userId;
            model.Status = (int)BillReshipStatus.待退货;
            model.CreateTime = DateTime.Now;
            model.SourceType = sourceType;
            model.StoreId = aftersales.StoreId;
            Insert(model);

            var list = new List<Corecmsbillreshipitem>();
            foreach (var item in aftersalesItems)
            {
                var reshipItem = new Corecmsbillreshipitem();
                reshipItem.ReshipId = model.ReshipId;
                reshipItem.OrderItemsId = item.OrderItemsId;
                reshipItem.GoodsId = item.GoodsId;
                reshipItem.ProductId = item.ProductId;
                reshipItem.Sn = item.Sn;
                reshipItem.Bn = item.Bn;
                reshipItem.Name = item.Name;
                reshipItem.ImageUrl = item.ImageUrl;
                reshipItem.Nums = item.Nums;
                reshipItem.Addon = item.Addon;
                reshipItem.CreateTime = DateTime.Now;
                list.Add(reshipItem);
                //保存退货单明细
            }

            var details = new List<Refshipdetail>();
            foreach (var item in billAftersalesDetails)
            {
                var reshipDetail = new Refshipdetail();
                reshipDetail.ReshipId = model.ReshipId;
                reshipDetail.ProductId = item.ProductId.Value;
                reshipDetail.SnCode = item.SnCode;

                details.Add(reshipDetail);
                //保存退货单明细
            }
             _refshipdetailService.InsertOrUpdate(details);
             _corecmsbillreshipitemService.InsertRange(list);

            jm.status = true;
            jm.data = model;

            return jm;
        }

        /// <summary>
        /// 查询导出表达式
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        private static Expressionable<Corecmsbillreship> QueryExp(CorecmsbillreshipQueryDto parm)
        {
            var predicate = Expressionable.Create<Corecmsbillreship>();
            predicate = predicate.AndIF(parm.BeginCreateTime == null, it => it.CreateTime >= DateTime.Now.AddDays(-365).ToShortDateString().ParseToDateTime());
            predicate = predicate.AndIF(parm.BeginCreateTime != null, it => it.CreateTime >= parm.BeginCreateTime);
            predicate = predicate.AndIF(parm.EndCreateTime != null, it => it.CreateTime <= parm.EndCreateTime);
            predicate = predicate.And(it => it.UserId == parm.UserId);
            predicate = predicate.And(it => it.SourceType == "1");

            return predicate;
        }
    }
}